﻿using HslCommunication;
using HslCommunication.MQTT;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;

namespace MyService.ServiceHandler
{
    public  class ServiceHandler
    {
        //至少俩个方法，一个是服务启动方法，一个是服务结束方法
        static HttpListener listener;

        // 定义INI文件的路径

        static string iniFilePath;

        //mqtt客户端定义
        static HslCommunication.MQTT.MqttClient mqttClient = new HslCommunication.MQTT.MqttClient(new MqttConnectionOptions());//连接java端mqtt服务的客户对象
        const string ServerClientId = "SERVER";

        static Dictionary<string, TBoxAlarm> TBoxDic = new Dictionary<string, TBoxAlarm>();

        public static async void Start()
        {
            //启动服务
            
            string ipv4 = GetLocalIPv4();
            listener = new HttpListener();
            listener.Prefixes.Add("http://" + ipv4 + ":8090/");
            listener.Start();

            ConnetMqttServer();

            #region 接受请求时，相应返回url地址加时间
            //Task.Run(() =>
            //{
            //    while (true)
            //    {
            //        //var content = listener.GetContext(); //阻塞
            //        //string url = content.Request.Url.ToString();
            //        //DateTime dateTime = DateTime.Now;

            //        //using (StreamWriter writer = new StreamWriter(content.Response.OutputStream))
            //        //{
            //        //    writer.WriteLine($"{url}+ {dateTime.ToLongTimeString()}");
            //        //}
            //        // 异步等待请求
            //        HttpListenerContext context = listener.GetContextAsync().Result;
            //        ProcessRequestAsync(context); // 异步处理请求

            //    }

            //});
            #endregion
            while (true)
            {
                //var content = listener.GetContext(); //阻塞
                //string url = content.Request.Url.ToString();
                //DateTime dateTime = DateTime.Now;

                //using (StreamWriter writer = new StreamWriter(content.Response.OutputStream))
                //{
                //    writer.WriteLine($"{url}+ {dateTime.ToLongTimeString()}");
                //}
                // 异步等待请求
                HttpListenerContext context = listener.GetContextAsync().Result;
                await ProcessRequestAsync(context); // 异步处理请求

            }

        }

        public static void Stop() { 
            //停止服务
            listener.Stop();
        }

        public static async Task ProcessRequestAsync(HttpListenerContext context)
        {
            // 获取请求信息
            HttpListenerRequest request = context.Request;
            HttpListenerResponse response = context.Response;
            string responseString = string.Empty;
            string requestUrl = request.RawUrl;
            string requestMethod = request.HttpMethod;

            // 根据请求方法和URL处理请求
            switch (requestMethod)
            {
                case "GET":
                    // 处理GET请求
                    responseString = "<html><body>Hello from GET request!</body></html>";
                    break;
                case "POST":
                    // 处理POST请求
                    using (Stream requestStream= request.InputStream)
                    {
                        using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
                        {
                            string requestBody = await reader.ReadToEndAsync();
                            Console.WriteLine(requestBody + "\n");
                            responseString = $"Received POST request with body: {requestBody}";
                            GranafaHttp granafaHttp = JsonConvert.DeserializeObject<GranafaHttp>(requestBody);
                            string title=granafaHttp.title;
                            string[] parts = title.Split('/');
                            string topic="V1/jlcmd/"+parts[0]+"/sensor/"+parts[1];
                            string name= granafaHttp.commonLabels.alertname;
                            bool exists = TBoxDic.TryGetValue(parts[2] + "/" + parts[3], out TBoxAlarm boxAlarm);
                            if (exists)
                            {
                                //如果存在字典里不存在 目标盒子/目标通道 的报警

                                //检查是否有关于 源盒子/源通道 的状态key-value
                                bool isSbox = boxAlarm.SBoxAlarm.TryGetValue(parts[0] + "/" + parts[1], out int Sint);
                                if (isSbox)
                                {
                                    //如果存在
                                    boxAlarm.SBoxAlarm[parts[0] + "/" + parts[1]]= int.Parse(granafaHttp.message);
                                }
                                else
                                {
                                    //如果不存在

                                    boxAlarm.SBoxAlarm.Add(parts[0] + "/" + parts[1], int.Parse(granafaHttp.message));
                                }
                              

                            }
                            else
                            {
                                //如果不存在字典里不存在 目标盒子/目标通道 的报警
                                TBoxAlarm tboxAlarm = new TBoxAlarm();
                                tboxAlarm.boxWarn.Normal = int.Parse(parts[4]);
                                tboxAlarm.boxWarn.Warning = int.Parse(parts[5]);
                                tboxAlarm.boxWarn.Error = int.Parse(parts[6]);
                                tboxAlarm.SBoxAlarm.Add(parts[0] + "/" + parts[1], int.Parse(granafaHttp.message));
                                tboxAlarm.TboxInt=int.Parse(granafaHttp.message);
                                TBoxDic.Add(parts[2] + "/" + parts[3], tboxAlarm);
                             }
                            TBoxDic[parts[2] + "/" + parts[3]].TboxInt= TBoxDic[parts[2] + "/" + parts[3]].boxWarn.Normal;
                            //计算 目标盒子/目标通道 的报警值
                            foreach (KeyValuePair<string,int>sboxValue in TBoxDic[parts[2] + "/" + parts[3]].SBoxAlarm)
                            {
                                if(sboxValue.Value== TBoxDic[parts[2] + "/" + parts[3]].boxWarn.Error)
                                {
                                    TBoxDic[parts[2] + "/" + parts[3]].TboxInt = TBoxDic[parts[2] + "/" + parts[3]].boxWarn.Error;
                                    break;
                                }
                                else if(sboxValue.Value == TBoxDic[parts[2] + "/" + parts[3]].boxWarn.Warning)
                                {
                                    TBoxDic[parts[2] + "/" + parts[3]].TboxInt = TBoxDic[parts[2] + "/" + parts[3]].boxWarn.Warning;
                                    break;
                                }
                            }

                            string value = "{\"value\":\"" + TBoxDic[parts[2] + "/" + parts[3]].TboxInt + "\"}";
                            var message = new HslCommunication.MQTT.MqttApplicationMessage()
                            {
                                
                                Topic = topic,
                                QualityOfServiceLevel = HslCommunication.MQTT.MqttQualityOfServiceLevel.AtMostOnce,
                                Payload = Encoding.UTF8.GetBytes(value)
                            };
                            if (mqttClient.IsConnected)
                            {
                                mqttClient.PublishMessageAsync(message);
                            }
                            else
                            {
                                OperateResult connect = mqttClient.ConnectServer();
                            }

                        }
                    }
                    //using (StreamReader reader = new StreamReader(request.InputStream, Encoding.UTF8))
                    //{
                    //    string requestBody = await reader.ReadToEndAsync();
                    //    responseString = $"Received POST request with body: {requestBody}";
                    //}
                    break;
                default:
                    // 处理其他请求方法
                    responseString = "<html><body>Invalid request method.</body></html>";
                    break;
            }

            // 设置响应内容类型和编码
            response.ContentType = "text/html";
            response.ContentEncoding = Encoding.UTF8;

            // 写入响应内容
            byte[] buffer = Encoding.UTF8.GetBytes(responseString);
            response.ContentLength64 = buffer.Length;
            Stream output = response.OutputStream;
            await output.WriteAsync(buffer, 0, buffer.Length);
            output.Close();
        }

        public static string GetLocalIPv4()
        {
            //根据主机名称解析主机的ip地址
            var ipv4s=Dns.GetHostAddresses(Dns.GetHostName())
                .Where(p=>p.AddressFamily==AddressFamily.InterNetwork)
                .Select(p=>p.MapToIPv4().ToString());   //筛选出所有ipv4地址
            if (ipv4s.Count() > 1)
            {
                return ipv4s.Where(p=>p.StartsWith("192")).FirstOrDefault(); //如果有多个ipv4s地址，返回以192开头的地址
            }
            else 
                return ipv4s.FirstOrDefault();

        }

        private static void ConnetMqttServer()
        {
            // 获取服务的二进制文件目录（假设INI文件位于同一目录下）
            string serviceDirectory = AppDomain.CurrentDomain.BaseDirectory;
            iniFilePath = Path.Combine(serviceDirectory, "config.ini");

            try
            {
                if (File.Exists(iniFilePath))//读取时先要判读INI文件是否存在
                {
                    IniFileHelper iniFileHelp = new IniFileHelper(iniFilePath);
                    
                    mqttClient.ConnectionOptions.ClientId = iniFileHelp.ReadConfig("MQTT", "Id");
                    mqttClient.ConnectionOptions.IpAddress = iniFileHelp.ReadConfig("MQTT", "ServerAddress");
                    mqttClient.ConnectionOptions.Port = int.Parse(iniFileHelp.ReadConfig("MQTT", "Port"));
                    mqttClient.ConnectionOptions.Credentials = new MqttCredential(iniFileHelp.ReadConfig("MQTT", "User"), iniFileHelp.ReadConfig("MQTT", "Passwd"));

                    OperateResult connect = mqttClient.ConnectServer();
                    if (!connect.IsSuccess)
                    {
                        Console.WriteLine("Connect failed: " + connect.Message);
                        return;
                    }

                    // mqttClient.ConnectClose();
                }
                else
                {
                    Console.WriteLine("INI文件不存在");
                }
            }
            catch
            {
                throw new Exception("配置文件不存在或权限不足导致无法读取");
            }

        }

    }
}
